/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package fr.adama.file;

import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.PdfWriter;
import fr.adama.constante.Constante;
import static fr.adama.constante.Constante.pathBulletin;
import fr.adama.dto.BulletinPaieDTO;
import fr.adama.dto.ContratDTO;
import fr.adama.dto.CumulsDTO;
import fr.adama.dto.ModelePaieDTO;
import fr.adama.exception.BulletinException;
import fr.adama.service.ContratService;
import fr.adama.util.AdamaMarshaller;
import fr.adama.util.DateFormatFactory;
import fr.adama.util.ZipUtil;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.PostConstruct;
import org.apache.velocity.app.VelocityEngine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.ui.velocity.VelocityEngineUtils;
import org.xhtmlrenderer.pdf.ITextRenderer;

/**
 *
 * @author avisto
 */
@Component
public class ExportFile {

    @Value("${outputFolder}")
    String outputFolder;
    @Autowired
    private VelocityEngine velocityEngine;
    @Autowired
    ContratService contratService;
    @Autowired
    AdamaMarshaller marshaller;

    private static final Logger logger = LoggerFactory.getLogger(ExportFile.class);

    @PostConstruct
    public void createDirectoryIfNotExist() {

        File folder = new File(outputFolder);
        if (!folder.exists()) {
            folder.mkdirs();
            logger.info("Création du folder d'output {}", folder.getAbsolutePath());
        }
    }

    public BulletinPaieDTO exportBulelletinPaie(BulletinPaieDTO bulletinPaie, ContratDTO contrat, ModelePaieDTO modelPaie, CumulsDTO cumul) {
        logger.info("Export du bulletin du contrat.id={} pour la periode={}", contrat.getId(), bulletinPaie.getPeriode());

        FileOutputStream baosPDF = null;

        File fileBulletinPaiePDF = null;
        File fileBulletinPaieModelXML = null;
        File fileBulletinCumulXML = null;
        File fileBulletinLigneHoraireXML = null;
        try {
            //TODO: ici export de bulletin selon le format /outputFolder/Adherent.id/Employe.id/bulletin/Annee/mois.zip
            File outputDirectory = new File(outputFolder);
            File directoryAdherent = new File(outputDirectory.getAbsoluteFile() + "/" + contrat.getAdherent().getId());
            File directoryEmploye = new File(directoryAdherent.getAbsoluteFile() + "/" + contrat.getEmploye().getId());
            File directoryBulletinPaie = new File(directoryEmploye.getAbsoluteFile() + "/" + pathBulletin);
            File directoryBulletinPaieAnnee = new File(directoryBulletinPaie.getAbsoluteFile() + "/" + bulletinPaie.getAnnee());
            directoryBulletinPaieAnnee.mkdirs();
            fileBulletinPaiePDF = new File(directoryBulletinPaieAnnee.getAbsoluteFile() + "/" + Constante.prefixBulletin + "-" + bulletinPaie.getMois() + ".pdf");

            fileBulletinPaieModelXML = new File(directoryBulletinPaieAnnee.getAbsoluteFile() + "/" + Constante.prefixModelPaie + "-" + bulletinPaie.getMois() + ".xml");

            fileBulletinCumulXML = new File(directoryBulletinPaieAnnee.getAbsoluteFile() + "/" + Constante.prefixCumul + "-" + bulletinPaie.getMois() + ".xml");

            fileBulletinLigneHoraireXML = new File(directoryBulletinPaieAnnee.getAbsoluteFile() + "/" + Constante.prefixLigneHoraire + "-" + bulletinPaie.getMois() + ".xml");

            File fileBulletinPaieZIP = new File(directoryBulletinPaieAnnee.getAbsoluteFile() + "/" + bulletinPaie.getMois() + ".zip");
            baosPDF = new FileOutputStream(fileBulletinPaiePDF);
            Calendar calendar = GregorianCalendar.getInstance();
            calendar.setTime(bulletinPaie.getPeriode());
            bulletinPaie.setContrat(contrat);
            Map<String, Object> map = new HashMap<>();
            map.put("bulletin", bulletinPaie);
            map.put("contrat", contrat);
            map.put("modelPaie", modelPaie);
            map.put("cumul", cumul);
            map.put("sdf", DateFormatFactory.getDateFormatDefaut());
            map.put("du", DateFormatFactory.getDateFormatDefaut().format(bulletinPaie.getPeriode()));

            calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
            map.put("au", DateFormatFactory.getDateFormatDefaut().format(calendar.getTime()));
            String body = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, "/paie.vm", "utf8", map);

            final ITextRenderer renderer = new ITextRenderer();

            renderer.setPDFVersion(PdfWriter.VERSION_1_7);
            renderer.setDocumentFromString(body);
            renderer.layout();
            renderer.createPDF(baosPDF);

            baosPDF.close();
            marshaller.marshal(modelPaie, fileBulletinPaieModelXML);
            marshaller.marshal(cumul, fileBulletinCumulXML);
            marshaller.marshal(bulletinPaie.getLigneHoraire(), fileBulletinLigneHoraireXML);
            ZipUtil.zipBulletinPaie(new File[]{fileBulletinPaieModelXML, fileBulletinPaiePDF, fileBulletinLigneHoraireXML, fileBulletinCumulXML}, fileBulletinPaieZIP);

            bulletinPaie.setPathToPdf(fileBulletinPaieZIP.getAbsolutePath());

        } catch (FileNotFoundException ex) {
            logger.error("Probleme de fichier", ex);
            throw new BulletinException(ex);
        } catch (DocumentException | IOException ex) {
            logger.error("Probleme de document", ex);
            throw new BulletinException(ex);
        } finally {
            try {
                baosPDF.close();
                fileBulletinPaiePDF.delete();
                fileBulletinPaieModelXML.delete();
                fileBulletinCumulXML.delete();
                fileBulletinLigneHoraireXML.delete();
            } catch (IOException ex) {
                logger.error("Probleme de fermeture du document", ex);
                throw new BulletinException(ex);
            }
        }
        return bulletinPaie;
    }

    public void manipulatePdf(String src, String dest) throws IOException, DocumentException {

    }

}
